package com.sz.biz.common.contract.service.impl;

import com.github.tobato.fastdfs.domain.StorePath;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
import com.google.common.collect.Lists;
import com.sz.biz.common.constants.CommCodes;
import com.sz.biz.common.constants.ModuleNames;
import com.sz.biz.common.contract.dto.*;
import com.sz.biz.common.contract.entity.ContContract;
import com.sz.biz.common.contract.service.ContTypeEnum;
import com.sz.biz.common.contract.service.ContractStatusEnum;
import com.sz.biz.common.contract.service.ContractTypeEnum;
import com.sz.biz.common.contract.service.ServiceTypeEnum;
import com.sz.biz.common.contract.service.ContContractService;
import com.sz.biz.common.contract.service.ContContractorService;
import com.sz.biz.common.contract.service.ContFieldService;
import com.sz.common.base.constants.TemplateConstants;
import com.sz.common.base.constants.UserActions;
import com.sz.common.base.dao.ParamData;
import com.sz.common.base.dto.QResultDto;
import com.sz.common.base.dto.QueryParams;
import com.sz.common.base.dto.ResultDto;
import com.sz.common.base.exception.Exceptions;
import com.sz.common.base.service.AbstractService;
import com.sz.biz.logistics.constants.ErrorCodes;
import com.sz.common.core.service.PrincipalLogUtils;
import com.sz.common.core.service.PrincipalUtils;
import com.sz.common.core.system.entity.SysFile;
import com.sz.common.core.system.service.SysFileService;
import com.sz.common.core.system.service.SysUserSupport;
import com.sz.common.core.system.service.UserModel;
import com.sz.common.core.system.dto.SimpleUserDto;
import com.sz.common.core.system.entity.User;
import com.sz.common.core.system.service.UserService;
import com.sz.common.core.system.utils.PDFUtils;
import com.sz.common.base.utils.DateUtils;
import com.sz.common.base.utils.EntityUtils;
import com.sz.common.base.utils.FreeMarkerTemplateUtils;
import com.sz.common.base.utils.UUIDGenerator;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.map.HashedMap;
import org.apache.commons.lang3.StringUtils;
import org.apache.tomcat.util.http.fileupload.ByteArrayOutputStream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.ByteArrayInputStream;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Package: com.sz.biz.common.contract.service.impl<br>
 * Function: TODO: ADD FUNCTION <br>
 * Author: yanhong.xiao.<br>
 * Date: 2017-07-21 09:09:00.
 */
@Service
public class ContContractServiceImpl extends AbstractService implements ContContractService {
    @Autowired
    private ContContractorService contContractorService;
    @Autowired
    private ContFieldService contFieldService;
    @Autowired
    private FastFileStorageClient storageClient;
    @Autowired
    private SysUserSupport sysUserSupport;
    @Autowired
    private UserService userService;
    @Autowired
    private SysFileService sysFileService;

    @Override
    protected String getMapperNamespace() {
        return "com.sz.biz.common.contract.entity.ContContractMapper";
    }

    private static Logger logger = LoggerFactory.getLogger(ContContractServiceImpl.class);

    /**
     * 保存合同数据
     * <p>
     * //检查数据必填项
     * //保存合同数据
     * //处理合同方数据
     * //处理fields数据
     * //草稿或者已生成状态---》已生成状态需要转pdf，保存到服务器上， 更新表数据
     *
     * @param contContractDto
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ContContractReturnDto saveContract(ContContractDto contContractDto) {
        ContContractReturnDto returnDto = new ContContractReturnDto();
        ContContract contract = new ContContract();
        if (null != contContractDto) {
            contContractDto.setType(ContractTypeEnum.getIntegerCode(ContractTypeEnum.CONT_TEMPLATE));
            EntityUtils.copyPropertiesIgnoreNull(contContractDto, contract);
            contract.setId(null);
            contract.setCreateUserId(PrincipalUtils.getAccountId());
            contract.setLastUpdateUserId(PrincipalUtils.getAccountId());
            //检验
            validateSaveContract(contract);
            if (StringUtils.isNotBlank(contContractDto.getContent())) {
                if (HtmlUtils.validateHtml(contContractDto.getContent())) {
                    //有非法字符
                    throw Exceptions.bizException(ErrorCodes.ERROR_CONT_TEMPLATE_CONTENT_INVALID);
                }
            }
            //校验甲方乙方
            if (null == contContractDto.getFirstContractorDto() || null == contContractDto.getSecondContractorDto()) {
                throw Exceptions.bizException(ErrorCodes.ERROR_CONT_CONTRACTOR_NOT_NULL);
            }
            String fileId = convertPdf(contContractDto);
            returnDto.setFileUrl(contContractDto.getFileUrl());
            returnDto.setFileName(contContractDto.getFileName());
            if (StringUtils.isNotBlank(fileId)) {
                contract.setFileId(fileId);
                contract.setGenFileTime(new Date());
            }
            //1.保存合同
            dao.save(getSqlName("insertSelective"), contract);
            //2.保存合同方
            List<ContContractorDto> contContractorDtoList = getContractorDtoList(contContractDto, contract.getId());
            contContractorService.batchSave(contContractorDtoList);
            //保存field
            List<ContFieldDto> fieldDtoList = getFieldDtoList(contContractDto, contract.getId());
            contFieldService.batchSave(fieldDtoList);
            Map<String, Object> dataBackup = new HashMap<>();
            dataBackup.put("ADD_CONT_CONTRACT", contContractDto);
            PrincipalLogUtils.addOperationLog(ModuleNames.CONT, ModuleNames.CONT_CONTRACT, UserActions.ADD, "新增合同", dataBackup);
        }
        returnDto.setId(contract.getId());
        return returnDto;
    }


    /**
     * 保存合同文件--自定义
     *
     * @param contContractFileDto
     * @return
     */
    @Override
    public ContContract saveContractFile(ContContractFileDto contContractFileDto) {
        contContractFileDto.setType(ContractTypeEnum.getIntegerCode(ContractTypeEnum.CONT_DEFINITION));
        ContContract contract = new ContContract();
        EntityUtils.copyPropertiesIgnoreNull(contContractFileDto, contract);
        contract.setId(null);
        //直接设置为已生成状态
        contract.setStatus(ContractStatusEnum.getIntegerCode(ContractStatusEnum.STATUS_GENERATE));
        //校验
        validateSaveContract(contract);
        if (null == contract.getCreateUserId()) {
            contract.setCreateUserId(PrincipalUtils.getAccountId());
        }
        if (null == contract.getCreateTime()) {
            contract.setCreateTime(new Date());
        }
        contract.setLastUpdateUserId(PrincipalUtils.getAccountId());
        //保存合同
        dao.save(getSqlName("insertSelective"), contract);
        Map<String, Object> dataBackup = new HashMap<>();
        dataBackup.put("ADD_CONT_CONTRACT", contContractFileDto);
        PrincipalLogUtils.addOperationLog(ModuleNames.CONT, ModuleNames.CONT_CONTRACT, UserActions.ADD, "新增合同", dataBackup);
        return contract;
    }

    @Override
    public ContContract getById(Integer id) {
        ContContract contract = (ContContract) dao.findForObject(getSqlName("selectByPrimaryKey"), id);
        return contract;
    }

    @Override
    public ContContractDto getDtoById(Integer id) {
        ContContractDto dto = null;
        if (null != id) {
            ContContract contract = getById(id);
            if (null == contract) {
                return dto;
            } else {
                dto = new ContContractDto();
                //获取template基本信息
                EntityUtils.copyPropertiesIgnoreNull(contract, dto);
                //处理创建人姓名
                UserModel userModel = sysUserSupport.getUserById(contract.getCreateUserId());
                dto.setCreateUserName(userModel.getAccountName());
                dto.setServiceTypeName(ServiceTypeEnum.valueOfEnum(String.valueOf(contract.getServiceType())).getName());
                //处理合同类型名称
                dto.setTypeName(ContractTypeEnum.valueOfEnum(String.valueOf(dto.getType())).getName());
                //处理文件的信息
                if (StringUtils.isNotBlank(contract.getFileId())) {
                    SysFile sysFile = sysFileService.getFileInfo(contract.getFileId());
                    dto.setFileUrl(sysFile.getFileLocation());
                    dto.setFileName(sysFile.getFileName());
                    dto.setFileId(sysFile.getFileId());
                    dto.setFileType(sysFile.getContentType());
                }
                dto.setStatusName(ContractStatusEnum.valueOfEnum(String.valueOf(dto.getStatus())).getName());
                //如果是基于模板创建的合同
                if (dto.getType().intValue() == ContractTypeEnum.getIntegerCode(ContractTypeEnum.CONT_TEMPLATE)) {
                    //处理合同方
                    Map<String, ContContractorDto> map = contContractorService.getContractorDtosByRelId(ContTypeEnum.CONT_CONTRACTOR, id);
                    ContContractorDto first = map.get(CommCodes.CONT_CONTRACTOR_FIRST_KEY);
                    if (null != first) {
                        dto.setFirstContractorDto(first);
                    }
                    ContContractorDto second = map.get(CommCodes.CONT_CONTRACTOR_SECOND_KEY);
                    if (null != second) {
                        dto.setSecondContractorDto(second);
                    }
                    //处理field
                    Map<String, String> contFields = contFieldService.getFields(ContTypeEnum.CONT_CONTRACTOR, id);
                    if (null != contFields) {
                        dto.setTitle(contFields.get(CommCodes.CONT_FIELD_TITLE_KEY));
                        dto.setContent(contFields.get(CommCodes.CONT_FIELD_CONTENT_KEY));
                    }
                }
                return dto;
            }
        }
        return dto;
    }

    /**
     * 修改合同
     *
     * @param contContractDto
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ContContractReturnDto updateContract(ContContractDto contContractDto) {
        ContContractReturnDto returnDto = new ContContractReturnDto();
        ContContract newContract = new ContContract();
        EntityUtils.copyPropertiesIgnoreNull(contContractDto, newContract);
        newContract.setType(ContractTypeEnum.getIntegerCode(ContractTypeEnum.CONT_TEMPLATE));
        //校验
        validateUpdateContract(newContract);

        if (StringUtils.isNotBlank(contContractDto.getContent())) {
            if (HtmlUtils.validateHtml(contContractDto.getContent())) {
                //有非法字符
                throw Exceptions.bizException(ErrorCodes.ERROR_CONT_TEMPLATE_CONTENT_INVALID);
            }
        }

        // 3.进行修改
        // 3.1 处理合同方,删除原来合同方，增加新的合同方
        List<Integer> relIds = Lists.newArrayList();
        relIds.add(contContractDto.getId());
        contContractorService.batchDeleteByRelIds(ContTypeEnum.CONT_CONTRACTOR, relIds);
        List<ContContractorDto> contContractorDtoList = getContractorDtoList(contContractDto, contContractDto.getId());
        contContractorService.batchSave(contContractorDtoList);
        //3.2 处理field，删除原来field，增加新的field
        contFieldService.batchDeleteByRelIds(ContTypeEnum.CONT_CONTRACTOR, relIds);
        List<ContFieldDto> fieldDtoList = getFieldDtoList(contContractDto, contContractDto.getId());
        contFieldService.batchSave(fieldDtoList);

        //判断是草稿还是已生成
        String fileId = convertPdf(contContractDto);
        returnDto.setFileUrl(contContractDto.getFileUrl());
        returnDto.setFileName(contContractDto.getFileName());
        newContract.setFileId(fileId);

        //3.3 修改合同模板
        dao.update(getSqlName("updateNull"), newContract);
        returnDto.setId(newContract.getId());

        Map<String, Object> dataBackup = new HashMap<>();
        dataBackup.put("UPDATE_CONT_CONTRACT", contContractDto);
        PrincipalLogUtils.addOperationLog(ModuleNames.CONT, ModuleNames.CONT_CONTRACT, UserActions.UPDATE, "修改合同", dataBackup);

        return returnDto;
    }

    /**
     * 修改合同文件
     *
     * @param contContractFileDto
     * @return
     */
    @Override
    public ContContract updateContractFile(ContContractFileDto contContractFileDto) {
        //修改合同文件
        ContContract newContract = new ContContract();
        EntityUtils.copyPropertiesIgnoreNull(contContractFileDto, newContract);
        newContract.setType(ContractTypeEnum.getIntegerCode(ContractTypeEnum.CONT_DEFINITION));
        //校验
        validateUpdateContract(newContract);
        if (null == newContract.getCreateUserId()) {
            newContract.setCreateUserId(PrincipalUtils.getAccountId());
        }
        dao.update(getSqlName("updateNull"), newContract);
        return newContract;
    }


    /**
     * 获取列表数据
     *
     * @param params
     * @return
     */
    @Override
    public ResultDto findSimpleDtoPages(QueryParams params) {
        ResultDto resultDto = new ResultDto();
        List<ContContractSimpleDto> dtoData = Lists.newArrayList();
        List<Integer> contractIds = Lists.newArrayList();
        List<String> fileIds = Lists.newArrayList();
        List<SimpleUserDto> users = Lists.newArrayList();
        List<Integer> createUserIds = Lists.newArrayList();
        Map<String, Object> selectParams = params.getParam();

        createUserIds.add(PrincipalUtils.getAccountId());
        params.put("createUserIds", createUserIds);
        ParamData pd = convertQueryParams(params);
        //1、根据条件查询
        List<ContContract> contractList = dao.findForList(getSqlName("findListPage"), pd, ContContract.class);
        if (CollectionUtils.isNotEmpty(contractList)) {
            //拼装数据
            contractList.forEach(contract -> {
                contractIds.add(contract.getId());
                createUserIds.add(contract.getCreateUserId());
                fileIds.add(contract.getFileId());
            });
            // 创建人的姓名
            Map<Object, SimpleUserDto> userMap = new HashedMap();
            if (CollectionUtils.isNotEmpty(users)) {
                //表示创建人都在这个集合中
                users.forEach(simpleUserDto -> {
                    userMap.put(simpleUserDto.getId(), simpleUserDto);
                });
            } else {
                //需要自己去查询一次
                List<User> createUsers = userService.findByIds(createUserIds);
                createUsers.forEach(user -> {
                    SimpleUserDto simpleUserDto = new SimpleUserDto();
                    EntityUtils.copyPropertiesIgnoreNull(user, simpleUserDto);
                    userMap.put(simpleUserDto.getId(), simpleUserDto);
                });
            }

            Map<String, SysFile> fileMap = new HashedMap();
            //获取文件信息
            if (CollectionUtils.isNotEmpty(fileIds)) {
                List<SysFile> files = sysFileService.getFileInfos(fileIds);
                if (CollectionUtils.isNotEmpty(files)) {
                    files.forEach(file -> {
                        fileMap.put(file.getFileId(), file);
                    });
                }

            }
            //合同模板的名称
            contractList.forEach(contract -> {
                ContContractSimpleDto dto = new ContContractSimpleDto();
                EntityUtils.copyPropertiesIgnoreNull(contract, dto);
                //处理文件信息
                if (contract.getStatus().intValue() == ContractStatusEnum.getIntegerCode(ContractStatusEnum.STATUS_GENERATE).intValue()) {
                    //已生成状态需要处理文件信息
                    SysFile file = fileMap.get(dto.getFileId());
                    if (null != file) {
                        dto.setFileUrl(file.getFileLocation());
                        dto.setFileName(file.getFileName());
                        dto.setFileType(file.getContentType());
                    }

                }
                //处理创建人姓名
                dto.setCreateUserName(userMap.get(dto.getCreateUserId()).getCode());
                //处理业务类型名称
                dto.setServiceTypeName(ServiceTypeEnum.valueOfEnum(String.valueOf(contract.getServiceType())).getName());
                //处理合同类型名称
                dto.setTypeName(ContractTypeEnum.valueOfEnum(String.valueOf(dto.getType())).getName());
                dto.setStatusName(ContractStatusEnum.valueOfEnum(String.valueOf(dto.getStatus())).getName());
                if (StringUtils.isBlank(dto.getTemplateName())) {
                    dto.setTemplateName("-");
                }
                dtoData.add(dto);
            });
            resultDto.setData(dtoData);
        }
        return new QResultDto(dtoData, pd.getPagination());

    }

    @Override
    public void batchDeleteByIds(List<Integer> ids) {
        if (CollectionUtils.isNotEmpty(ids)) {
            int createUserId = PrincipalUtils.getAccountId();
            Map<String, Object> map = new HashedMap();
            map.put("createUserId", createUserId);
            map.put("ids", ids);
            dao.update(getSqlName("batchUpdateIsDelete"), map);
        }
    }


    /**
     * 处理甲方，乙方数据
     *
     * @param contContractDto
     * @param contractId
     * @return
     */
    private List<ContContractorDto> getContractorDtoList(ContContractDto contContractDto, Integer contractId) {
        //甲方
        ContContractorDto firstContractorDto = contContractDto.getFirstContractorDto();
        firstContractorDto.setType(Integer.valueOf(ContTypeEnum.CONT_CONTRACTOR.getCode()));
        firstContractorDto.setContractorType(CommCodes.CONT_CONTRACTOR_FIRST);
        firstContractorDto.setRelId(contractId);
        //乙方
        ContContractorDto secondContractorDto = contContractDto.getSecondContractorDto();
        secondContractorDto.setType(Integer.valueOf(ContTypeEnum.CONT_CONTRACTOR.getCode()));
        secondContractorDto.setContractorType(CommCodes.CONT_CONTRACTOR_SECOND);
        secondContractorDto.setRelId(contractId);
        List<ContContractorDto> contContractorDtoList = Lists.newArrayList();
        contContractorDtoList.add(firstContractorDto);
        contContractorDtoList.add(secondContractorDto);
        return contContractorDtoList;

    }


    private List<ContFieldDto> getFieldDtoList(ContContractDto contractDto, Integer contractId) {
        List<ContFieldDto> fieldDtoList = Lists.newArrayList();
        ContFieldDto titleDto = new ContFieldDto();
        titleDto.setType(ContTypeEnum.getIntegerCode(ContTypeEnum.CONT_CONTRACTOR));
        titleDto.setRelId(contractId);
        titleDto.setFieldKey(CommCodes.CONT_FIELD_TITLE_KEY);
        titleDto.setFieldValue(contractDto.getTitle());
        titleDto.setOrderNum(1);
        fieldDtoList.add(titleDto);

        ContFieldDto contentDto = new ContFieldDto();
        contentDto.setType(ContTypeEnum.getIntegerCode(ContTypeEnum.CONT_CONTRACTOR));
        contentDto.setRelId(contractId);
        contentDto.setFieldKey(CommCodes.CONT_FIELD_CONTENT_KEY);
        contentDto.setFieldValue(contractDto.getContent());
        contentDto.setOrderNum(2);
        fieldDtoList.add(contentDto);
        return fieldDtoList;
    }


    private String convertPdf(ContContractDto dto) {
        ContractStatusEnum statusEnum = ContractStatusEnum.valueOfEnum(String.valueOf(dto.getStatus()));
        String fileUrl = null;
        if (null != statusEnum) {
            if (statusEnum == ContractStatusEnum.STATUS_GENERATE) {
                //已生成状态
                Map<String, Object> model = new HashedMap();
                model.put("title", dto.getTitle());
                if (null != dto.getFirstContractorDto()) {
                    if (null != dto.getFirstContractorDto().getSignName()) {
                        dto.getFirstContractorDto().setSignTimeStr(DateUtils.formatDate(dto.getFirstContractorDto().getSignTime(), DateUtils.FORMAT_DETAIL));
                    }
                }

                if (null != dto.getSecondContractorDto()) {
                    if (null != dto.getSecondContractorDto().getSignName()) {
                        dto.getSecondContractorDto().setSignTimeStr(DateUtils.formatDate(dto.getSecondContractorDto().getSignTime(), DateUtils.FORMAT_DETAIL));
                    }
                }
                model.put("first", dto.getFirstContractorDto());
                model.put("second", dto.getSecondContractorDto());
                model.put("content", dto.getContent());
                String html = FreeMarkerTemplateUtils.freeMarkerRender(model, TemplateConstants.CONT_CONTRACT);
                html = FreeMarkerTemplateUtils.tidyHtml(html);
                ByteArrayOutputStream outputStream = null;
                try {
                    outputStream = (ByteArrayOutputStream) PDFUtils.getPdfStream(html);
                    ByteArrayInputStream swapStream = new ByteArrayInputStream(outputStream.toByteArray());
                    long size = outputStream.toByteArray().length;
                    StorePath storePath = storageClient.uploadFile(swapStream, size,
                            "pdf", null);
                    SysFile sysFile = sysFileService.uploadFile(0, null, UUIDGenerator.generateOrderedUUID() +
                            ".pdf", "application/pdf", "ContractPdf", storePath.getFullPath(), size);
                    dto.setFileUrl(sysFile.getFileLocation());
                    dto.setFileName(sysFile.getFileName());
                    return sysFile.getFileId();
                } catch (Exception e) {
                    e.printStackTrace();
                    logger.info("合同文件生成pdf异常");
                    throw Exceptions.bizException(ErrorCodes.ERROR_CONT_GENERATE_PDF_FAIL);

                }

            }
        }
        return fileUrl;
    }

    /**
     * 合同的校验
     * //合同的名称不能为空,业务类型不能为空,状态不能为空
     * //模板合同的模板id不能为空, 自定义合同的文件地址不能为空
     *
     * @param contract
     * @return
     */
    private Boolean validateSaveContract(ContContract contract) {
        if (StringUtils.isBlank(contract.getTitle())) {
            throw Exceptions.bizException(ErrorCodes.ERROR_CONT_TITLE_NOT_NULL);
        }
        if (null == contract.getServiceType()) {
            throw Exceptions.bizException(ErrorCodes.ERROR_CONT_TITLE_SERVICETYPE_NULL);
        }
        if (null == contract.getStatus()) {
            throw Exceptions.bizException(ErrorCodes.ERROR_CONT_STATUS_NOT_NULL);
        }
        if (contract.getType().intValue() == ContractTypeEnum.getIntegerCode(ContractTypeEnum.CONT_TEMPLATE).intValue()) {
            //基于合同创建的模板,模板id不能为空
            if (StringUtils.isBlank(contract.getTemplateName())) {
                throw Exceptions.bizException(ErrorCodes.ERROR_CONT_TEMPLATE_NAME_NOT_NULL);
            }
        }
        if (contract.getType().intValue() == ContractTypeEnum.getIntegerCode(ContractTypeEnum.CONT_DEFINITION).intValue()) {
            if (StringUtils.isBlank(contract.getFileId())) {
                throw Exceptions.bizException(ErrorCodes.ERROR_CONT_FILE_NOT_NULL);
            }
        }
        return true;
    }


    /**
     * 修改合同的校验
     * //  合同是否存在
     * //是否有权限修改
     * // 模板合同的合同名称不能修改，
     *
     * @param contract
     * @return
     */
    private Boolean validateUpdateContract(ContContract contract) {

        // 1.判断该合同是否存在，
        if (contract.getId() <= 0) {
            throw Exceptions.bizException(ErrorCodes.ERROR_CONT_NOT_EXISTS);
        }
        ContContract oldContract = getById(contract.getId());
        if (null == oldContract) {
            throw Exceptions.bizException(ErrorCodes.ERROR_CONT_NOT_EXISTS);
        }
        //2.判断该合同模板是否为当前用户的合同的模板
        if (oldContract.getCreateUserId().intValue() != PrincipalUtils.getAccountId()) {
            throw Exceptions.bizException(ErrorCodes.ERROR_CONT_UPDATE_NO_AUTH);
        }

        if (contract.getType().intValue() == ContractTypeEnum.getIntegerCode(ContractTypeEnum.CONT_TEMPLATE)) {
            //检验合同模板的名称不能修改
            if (!oldContract.getTemplateName().equals(contract.getTemplateName())) {
                throw Exceptions.bizException(ErrorCodes.ERROR_CONT_TEMPLATE_NAME_CAN_NOT_UPDATE);
            }
        }

        contract.setIsDeleted(oldContract.getIsDeleted());
        if (oldContract.getStatus().intValue() == ContractStatusEnum.getIntegerCode(ContractStatusEnum.STATUS_GENERATE).intValue()) {
            //该合同已经是已生成状态了
            throw Exceptions.bizException(ErrorCodes.ERROR_CONT_GENERATED_CANNOT_UPDATE);
        }
        return true;
    }


}
